/*
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 *
 */
package com.googlecode.ivybeans.module;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.URL;
import org.netbeans.api.project.Project;
import org.netbeans.api.project.ProjectManager;
import org.netbeans.api.project.ant.AntBuildExtender;
import org.openide.filesystems.FileObject;
import org.openide.filesystems.FileSystem;
import org.openide.filesystems.FileUtil;
import org.openide.filesystems.Repository;
import org.openide.util.Exceptions;
import org.openide.xml.XMLUtil;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;

/**
 *
 * @author lforet
 */
public class IvyBuildHelper {

    private static IvyBuildHelper instance;

    private IvyBuildHelper() {
    }

    public static IvyBuildHelper getInstance() {
        if (instance == null) {
            instance = new IvyBuildHelper();
        }
        return instance;
    }

    public void createIvyImpl(Project project, File descriptorFile, File settingsFile, URL settingsURL) {
        try {
            clean(project);
            FileObject projDir = project.getProjectDirectory();
            FileSystem sfs = Repository.getDefault().getDefaultFileSystem();
            FileObject templateFO = sfs.findResource("Templates/ivybeans/ivy-impl.xml"); // NOI18N
            assert templateFO != null;

            FileObject ivyBuildFile = FileUtil.copyFile(templateFO, projDir.getFileObject("nbproject"), "ivy-impl"); // NOI18N
            Document ivyBuildDoc = XMLUtil.parse(new InputSource(ivyBuildFile.getInputStream()), false, true, null, null);

            NodeList retrieveElements = ivyBuildDoc.getElementsByTagNameNS("antlib:fr.jayasoft.ivy.ant", "resolve"); //NOI18N
            for (int i = 0; i < retrieveElements.getLength(); i++) {
                Element retrieveElement = (Element) retrieveElements.item(i);
                String descriptorPath = FileHelper.getInstance().getPath(project.getProjectDirectory(), descriptorFile);
                retrieveElement.setAttribute("file", descriptorPath); // NOI18N
                if (settingsFile != null) {
                    String settingsPath = FileHelper.getInstance().getPath(project.getProjectDirectory(), settingsFile);
                    Element configureElement = ivyBuildDoc.createElementNS("antlib:fr.jayasoft.ivy.ant", "ivy:settings");
                    configureElement.setAttribute("file", settingsPath);
                    retrieveElement.getParentNode().insertBefore(configureElement, retrieveElement);
                } else if (settingsURL != null) {
                    Element configureElement = ivyBuildDoc.createElementNS("antlib:fr.jayasoft.ivy.ant", "ivy:settings");
                    configureElement.setAttribute("url", settingsURL.toString());
                    retrieveElement.getParentNode().insertBefore(configureElement, retrieveElement);
                }
            }
            XMLUtil.write(ivyBuildDoc, new FileOutputStream(FileUtil.toFile(ivyBuildFile)), "UTF-8"); // NOI18N

            addBuildExtension(project);
        } catch (IOException ex) {
            Exceptions.printStackTrace(ex);
        } catch (SAXException ex) {
            Exceptions.printStackTrace(ex);
        }
    }

    public void clean(Project project) {
        try {
            FileObject projDir = project.getProjectDirectory();
            FileObject ivyBuildFile = projDir.getFileObject("nbproject/ivy-impl.xml"); // NOI18N
            if (ivyBuildFile != null) {
                FileUtil.toFile(ivyBuildFile).delete();
                removeBuildExtension(project);
            }
        } catch (IOException iOException) {
            Exceptions.printStackTrace(iOException);
        }
    }

    private void addBuildExtension(Project project) throws IOException {
        FileObject projDir = project.getProjectDirectory();
        FileObject ivyBuildFile = projDir.getFileObject("nbproject/ivy-impl.xml"); // NOI18N
        AntBuildExtender extender = project.getLookup().lookup(AntBuildExtender.class);
        assert extender != null;
        assert ivyBuildFile != null;
        if (extender.getExtension("ivy") == null) { // NOI18N
            AntBuildExtender.Extension ext = extender.addExtension("ivy", ivyBuildFile); // NOI18N
            // JSEProject extensible targets :  "-do-init", "-init-check", "-post-clean", "jar", "-pre-pre-compile","-do-compile","-do-compile-single" 
            ext.addDependency("-do-init", "-ivy-retrieve"); // NOI18N
//            ext.addDependency("-do-compile-single", "-ivy-retrieve"); // NOI18N
            ext.addDependency("jar", "-ivy-publish"); // NOI18N
            ext.addDependency("-post-clean", "-ivy-clean"); // NOI18N
        }
        ProjectManager.getDefault().saveProject(project);
    }

    private void removeBuildExtension(Project project) throws IOException {
        AntBuildExtender extender = project.getLookup().lookup(AntBuildExtender.class);
        assert extender != null;
        if (extender.getExtension("ivy") != null) { // NOI18N
            extender.removeExtension("ivy"); // NOI18N
        }
        ProjectManager.getDefault().saveProject(project);
    }
}
